import axios from 'axios';
import * as THREE from 'three';
import { lngLatToMercator } from './index';
const textureLoader = new THREE.TextureLoader();
export default class {
  list: any[];
  url: string;
  group: THREE.Group;
  constructor(url) {
    this.url = url;
    this.list = [];
    this.group = new THREE.Group();
  }
  async load() {
    const res = await axios.get(this.url);
    res.data.forEach(item => {
      const mark = this.create3DMarker(item);
      mark.visible = false;
      this.group.add(mark);
      this.list.push(mark);
    });
  }
  update(time) {
    this.list.forEach(item => {
      const [cone, point, wave] = item.children;
      item.rotation.z = time * Math.PI * 0.001;
      wave.userData.start += 0.007;
      const { start } = wave.userData;
      wave.scale.set(start, start, start);
      wave.material.opacity = Math.sin(time * Math.PI * 0.0006);
      if (wave.material.opacity < 0) {
        wave.userData.start = 0.3;
      }
    });
  }
  get(name) {
    return this.list.find(item => item.name === name);
  }
  getData(name) {
    const mark = this.get(name);
    if (mark) {
      return mark.userData;
    }
  }
  show(name) {
    this.list.forEach(item => (item.visible = false));
    const mark = this.get(name);
    if (mark) {
      mark.visible = true;
    }
  }
  create3DMarker(data) {
    const group = new THREE.Group();
    group.name = data.name;
    group.userData = data;
    const color = new THREE.Color('#0ff');
    const point = lngLatToMercator(data.position);
    const waveMap = textureLoader.load('ware.png');
    group.add(this.createCone(color));
    group.add(this.createPoint());
    group.add(this.createWave(waveMap, color));
    group.position.set(point.x, point.y, 11);
    return group;
  }
  xxxGeometry(radius = 1, height, count) {
    const vertices: any[] = [];
    for (let i = 0; i <= count; i++) {
      const x: number = Math.cos(((Math.PI * 2) / count) * i) * radius;
      const z: number = Math.sin(((Math.PI * 2) / count) * i) * radius;
      const x2: number = Math.cos(((Math.PI * 2) / count) * (i + 1)) * radius;
      const z2: number = Math.sin(((Math.PI * 2) / count) * (i + 1)) * radius;
      const p1 = [x, height * (3 / 5), z, x2, height * (3 / 5), z2];
      const p3 = [0, height, 0];
      const p4 = [0, 0, 0];
      vertices.push(...p1, ...p3, ...p1, ...p4);
    }
    const geometry = new THREE.BufferGeometry();
    geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
    return geometry;
  }
  createCone(color) {
    const geometry = new THREE.BoxGeometry(2, 2, 2);
    const material = new THREE.MeshPhongMaterial({
      color,
      side: THREE.DoubleSide
    });
    var mesh = new THREE.Mesh(geometry, material);
    mesh.rotateX(Math.PI * 0.25);
    mesh.rotateY(Math.PI * 0.25);
    mesh.position.z = 2;
    return mesh;
  }
  createPoint() {
    var geometry = new THREE.PlaneGeometry(3, 3);
    var material = new THREE.MeshBasicMaterial({
      transparent: true,
      depthWrite: false,
      map: textureLoader.load('dot2.png')
    });
    var mesh = new THREE.Mesh(geometry, material);
    return mesh;
  }
  createWave(map, color) {
    var geometry = new THREE.PlaneGeometry(10, 10);
    var material = new THREE.MeshBasicMaterial({
      color,
      opacity: 1.0,
      alphaMap: map,
      depthWrite: false,
      transparent: true
    });
    var mesh = new THREE.Mesh(geometry, material);
    mesh.scale.set(1, 1, 1);
    mesh.userData.size = 1;
    mesh.userData.start = Math.random();
    return mesh;
  }
}
